from django.shortcuts import render
# 导入Response包
from rest_framework.response import Response

# 导入django自带或的验证
from django.db.models import Q

# 导入不需要验证token实现访问路由
from rest_framework.permissions import AllowAny

# 使用手机号或邮箱登录(修改验证方式)
from django.contrib.auth.backends import ModelBackend

# 导入rest_framework_jwt模块
from rest_framework_jwt.settings import api_settings

# 解析jwt_token的模块
from rest_framework_jwt.utils import jwt_decode_handler

# 导入APIView包
from rest_framework.views import APIView

# 阿里云短信服务包
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest

# 导入随机包
import random

# 导入序列化器
from miaoapp.miaoser import *

# 用户验证方式
from django.contrib.auth import authenticate

# 发送邮件
from django.core.mail import send_mail
from miao_django.settings import DEFAULT_FROM_EMAIL

# 七牛云
from qiniu import Auth

# 导入redis
import redis

# 设置redis连接域名
host = '127.0.0.1'
port = 6379
# 连接redis
r = redis.Redis(host=host, port=port, decode_responses=True)


# 七牛云token
class QiNiu(APIView):
    def get(self, request):
        q = Auth('wRxIPvd7vuUXBk99XS-mHpYIbzW3hW96izO0unAF', 'tFka3pVepUwf9N8qCk6vENICaNDRDbJglfrZoVEh')
        token = q.upload_token('miaomiaoc')
        return Response({
            'token': token
        })


# 获取用户公司信息
class CompanyInfo(APIView):
    def get(self, request):
        # 获取用户
        token = request.GET.get('token', None)
        # 解析token
        user = jwt_decode_handler(token)
        # 获取用户id
        uid = user.get('user_id')
        user = User.objects.get(id=int(uid))
        # 查询用户所属公司
        company = Company.objects.filter(id=int(user.company)).first()
        # 序列化用户公司信息
        companyinfo = CompanySer(company).data
        # 返回
        return Response({'code': 200, 'companyinfo': companyinfo})

    def put(self, request):
        # 获取修改的公司信息
        data = request.data
        # 从数据库中查询
        company = Company.objects.get(id=int(data['id']))
        # 修改数据
        company.name = data['name']
        company.town = data['town']
        company.street = data['street']
        company.logo = data['logo']
        # 保存
        company.save()
        return Response({'code': 200, 'message': '修改成功'})


# 修改密码
class UpdatePwd(APIView):
    def put(self, request):
        # 获取参数
        userdata = request.data
        UpdateForm = userdata['UpdateForm']
        PassWordForm = userdata['PassWordForm']
        # 查询验证码是否超时
        code = r.get(str(UpdateForm['email']))
        if not code:
            return Response({'code': 405, 'message': '验证码已超时，请重新获取'})
        # 判断前端验证码与后端验证码是否一致
        if PassWordForm['code'] != code:
            return Response({'code': 405, 'message': '验证码输入有误'})
        # 数据库中获取该用户的信息
        user = User.objects.filter(username=UpdateForm['username']).first()
        # 如果该用户不存在
        if not user:
            return Response({'code': 405, 'message': '数据有误'})
        # 修改密码
        user.set_password(PassWordForm['password'])
        user.save()
        return Response({'code': 200, 'message': '密码重置成功'})


# 审核操作
class AdminAuditing(APIView):
    def put(self, request):
        # 获取被审核用户id
        user = request.data.get('uid', None)
        bear = request.data.get('bear', None)
        content = request.data.get('content', None)
        print(user)
        print(user['id'])
        if bear == '通过审核':
            # 修改对应用户的审核结果
            user = User.objects.filter(id=int(user['id'])).first()
            print(user.auditing)
            user.auditing = 1
            # 修改后保存
            user.save()
            return Response({'code': 200, 'message': '通过审核'})
        elif bear == '拒绝申请':
            # 修改对应用户的审核结果
            user = User.objects.filter(id=int(user['id'])).first()
            user.auditing = 2
            if bear:
                user.refuse = content
            # 修改后保存
            user.save()
            return Response({'code': 405, 'message': '拒绝成功'})


# 路由拦截
class BeforeEach(APIView):
    def get(self, request):
        token = request.GET.get('0', None)
        user = jwt_decode_handler(token)
        uid = user.get('user_id')
        # 获取用户权限
        userpower = UserPower.objects.filter(uid=int(uid)).first()
        power = Power.objects.filter(id=int(userpower.pid)).first()

        if power.pname != '管理员':
            return Response({'code': 405, 'message': '访问此页面需要管理员权限'})
        else:
            return Response({'code': 200})


def UserList(userinfo):
    # 遍历查询该用户的所有权限
    for user in userinfo:
        uid = int(user['id'])
        power = UserPower.objects.filter(uid=int(uid)).first()
        powerlist = UserPowerSer(power).data
        # 将权限添加到用户info中
        user['power'] = powerlist['pid']
    return userinfo


# 获取用户信息
class UserInfo(APIView):
    def get(self, request):
        # 获取需要获取的用户类型
        active_name = request.GET.get('activeName', None)
        token = request.GET.get('token', None)
        user = jwt_decode_handler(token)
        uid = user.get('user_id')
        userpower = UserPower.objects.filter(uid=int(uid)).first()
        power = Power.objects.filter(id=int(userpower.pid)).first()

        # 当前页面
        page = request.GET.get('page', None)
        # 一页有多少条商品
        size = request.GET.get('size', None)

        # 获取所有用户信息(归档除外)
        if not page:
            users = User.objects.filter(is_delete=0,auditing=1)
            userinfo = UserSer(users, many=True).data
            return Response({'code': 200, 'userinfo': userinfo})

        # 定义从哪开始切片
        data_start = (int(page) - 1) * int(size)
        # 定义切到哪
        data_end = int(page) * int(size)

        if power.pname != '管理员':
            users = User.objects.filter(id=int(uid))[data_start:data_end]
            total = User.objects.filter(id=int(uid)).count()
            userinfo = UserSer(users, many=True).data
            userinfo = UserList(userinfo)
        else:
            # 获取全部用户(只返回未归档的用户)
            if active_name == '全部':
                users = User.objects.filter(is_delete=0)[data_start:data_end]
                total = User.objects.filter(is_delete=0).count()
                userinfo = UserSer(users, many=True).data

            # 获取待审核的用户
            elif active_name == '待审核':
                userlist = User.objects.filter(auditing=0, is_delete=0)[data_start:data_end]
                total = User.objects.filter(auditing=0, is_delete=0).count()
                userinfo = UserSer(userlist, many=True).data

            # 获取审核通过的用户(只返回未归档的用户)
            elif active_name == '审核通过':
                userlist = User.objects.filter(auditing=1, is_delete=0)[data_start:data_end]
                total = User.objects.filter(auditing=1, is_delete=0).count()
                userinfo = UserSer(userlist, many=True).data

            # 获取拒绝注册的用户
            else:
                userlist = User.objects.filter(auditing=2, is_delete=0)[data_start:data_end]
                total = User.objects.filter(auditing=2, is_delete=0).count()
                userinfo = UserSer(userlist, many=True).data

            # 调用方法
            userinfo = UserList(userinfo)
        return Response({'code': 200, 'userinfo': userinfo, 'total': total})

    def post(self, request):
        data = request.data
        # 获取添加参数
        userdata = data['UserForm']
        token = data['token']
        user = jwt_decode_handler(token)
        uid = user.get('user_id')
        userpower = UserPower.objects.filter(uid=int(uid)).first()
        power = Power.objects.filter(id=int(userpower.pid)).first()
        if power.pname != '管理员':
            return Response({'cide': 405, 'message': '只有管理员才可以添加用户'})

        # 将注册信息入库
        user = User.objects.create_user(username=userdata['username'], password=userdata['password'],
                                        phone=userdata['phone'], company=userdata['company']
                                        )
        # 获取申请权限的id
        power = Power.objects.filter(pname=userdata['power']).first()
        # 将申请的管理员权限入库
        UserPower.objects.create(pid=power.id, uid=user.id)
        return Response({'code': 200, 'message': '添加成功，等待管理员审核'})

    def put(self, request):
        # 获取数据
        userdata = request.data
        # 判断数据是否为空
        if not userdata:
            return Response({'code': 405, 'message': '信息错误'})
        # 获取用户信息
        user = User.objects.get(id=int(userdata['id']))
        if not user:
            return Response({'code': 200, 'message': '该用户不存在'})
        # 修改相关字段信息
        user.username = userdata['username']
        user.phone = userdata['phone']
        user.company = userdata['company']
        user.email = userdata['email']
        # 获取用户权限关系表信息
        power = UserPower.objects.filter(uid=int(userdata['id'])).first()
        # 修改用户权限关系表
        power.pid = userdata['power']
        # 保存
        user.save()
        power.save()
        return Response({'code': 200, 'message': '修改成功'})

    def delete(self, request):
        # 获取归档的用户id
        uid = request.GET.get('uid', None)
        # 查询该用户信息
        user = User.objects.filter(id=int(uid)).first()
        # 如果不存在
        if not user:
            return Response({'code': 405, 'message': '数据有误'})
        # 将此用户逻辑删除
        user.is_delete = 1
        user.save()
        return Response({'code': 200, 'message': '归档成功'})


# 重新用户登录返回函数
def jwt_response_payload_handler(token, user=None, request=None):
    '''
    :param token: jwt生成的token值
    :param user: User对象
    :param request: 请求
    '''
    return {
        'token': token,
        'user_id': user.id,
    }


# 为登录增加手机登录和邮箱登录
class UsernameMobileAuthBackend(ModelBackend):
    # 重写验证方式
    def authenticate(self, request, username=None, password=None, **kwargs):
        user = User.objects.get(Q(username=username) | Q(phone=username) | Q(email=username))
        if user is not None and user.check_password(password):
            return user


# 登录
class Login(APIView):
    def post(self, request):
        userdata = request.data
        user = authenticate(username=userdata['username'], password=userdata['password'])
        # 判断用户或密码是否正确
        if not user:
            return Response({'code': 405, 'message': '用户名或密码错误'})
        # 判断用户是否已被归档
        if user.is_delete == 1:
            return Response({'code': 405, 'message': '用户信息已删除，请联系管理员'})
        # 用户待审核中
        elif user.auditing == 0:
            return Response({'code': 405, 'message': '待管理员审核中'})
        # 用户审核失败
        elif user.auditing == 2:
            # 将失败原因传给前端
            return Response({'code': 405, 'message': '审核失败', 'refuse': user.refuse})

        # 登录成功
        # 生成jwt
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        powerPid = UserPower.objects.filter(uid=int(user.id)).first()
        resp = {'code': 200, 'message': '登录成功', 'token': token, 'username': user.username, 'photo': user.photo,
                'pid': powerPid.pid}
        return Response(resp)


# 注册
class Register(APIView):
    def post(self, request):
        # 获取注册参数
        userdata = request.data
        # 获取redis中的验证码
        code = r.get(str(userdata['phone']))
        # 判断验证码是否过期
        if not code:
            return Response({'code': 405, 'message': '验证码超时'})
        # 判断验证码是否正确
        if userdata['code'] != code:
            return Response({'code': 405, 'message': '验证码输入有误'})
        # 将注册信息入库
        user = User.objects.create_user(username=userdata['username'], password=userdata['password'],
                                        phone=userdata['phone'], company=userdata['company']
                                        )
        # 获取申请权限的id
        power = Power.objects.filter(pname=userdata['power']).first()
        # 将申请的管理员权限入库
        UserPower.objects.create(pid=power.id, uid=user.id)
        return Response({'code': 200, 'message': '注册成功，等待管理员审核'})


# 获取权限及公司列表
class PowerList(APIView):
    permission_classes = [AllowAny]
    def get(self, request):
        # 获取所有权限
        power = Power.objects.all()
        # 获取所有公司
        company = Company.objects.all()
        # 序列化权限数据
        powerlist = PowerSer(power, many=True).data
        # 序列化公司数据
        complist = CompanySer(company, many=True).data
        return Response({'code': 200, 'powerlist': powerlist, 'complist': complist})


# 生成验证码
def Code():
    code = ''
    a = 0
    # 无限循环
    while 1:
        # 循环一次，生成一个数字
        code_index = random.randrange(0, 10)
        # 将每次生成的数字拼接成一个字符串
        code += str(code_index)
        # 循环一次+1
        a += 1
        # 当循环6次后停止循环
        if a == 6:
            break
    # 返回生成的验证码
    return code


# 邮箱验证
class SendEmailCode(APIView):
    # 邮件验证码请求的接口
    def post(self, request):
        # 获取参数
        username = request.data.get('username', None)
        email = request.data.get('email')
        user = User.objects.filter(username=username).first()
        if not user:
            return Response({'code': 405, 'message': '请输入正确的用户名'})

        email_code = r.get(email)
        # 查看该邮箱是否在五分钟之内请求过
        if email_code:
            return Response({'code': 405, 'message': '邮箱验证码有效时间为5分钟'})

        # 生成验证码
        email_code = Code()
        # 主题
        subject = '密码找回邮件'
        # 内容
        # message = '你的邮箱验证码是:%s' % email_code
        message = '你的邮箱验证码是:%s' % email_code + '/t/n' + '如果重修页面无法显示，点击一下网站进行修改密码操作' + 'http://127.0.0.1:8080/UpPwd'
        # 本次请求存入redis中
        r.set(email, str(email_code))  # 存储到redis
        # 设置访问周期为5分钟
        r.expire(email, 5 * 60)
        send_mail(subject, message, DEFAULT_FROM_EMAIL,
                  [email])  # 把邮件发过去
        return Response({'code': 200, 'message': '验证码发送至您邮箱，请注意查收'})


# 短信请求接口
class SendAlysms(APIView):
    def post(self, request):
        resp = {}
        phone = request.data.get('phone', None)
        # 阿里云个人账户的ak，sk
        AK = 'LTAI4GHJyuRw9ZgARVLCsZ18'
        SK = 'W1J92QOwIYLCEbZeGXLI8UhiztSMj9'
        client = AcsClient(AK, SK, 'cn-hangzhou')
        # 调用验证码生成接口
        code = Code()
        if r.get(str(phone)):
            resp['code'] = 405
            resp['message'] = '获取验证码间隔小于一分钟'
            return Response(resp)
        request = CommonRequest()
        request.set_accept_format('json')
        request.set_domain('dysmsapi.aliyuncs.com')
        request.set_method('POST')
        request.set_protocol_type('https')  # https | http
        request.set_version('2017-05-25')
        request.set_action_name('SendSms')

        request.add_query_param('RegionId', "cn-hangzhou")
        # 手机号
        request.add_query_param('PhoneNumbers', str(phone))
        # 验证码可以随机获取
        request.add_query_param('TemplateParam', str({'code': code}))
        request.add_query_param('SignName', "秒妙测")
        request.add_query_param('TemplateCode', "SMS_190267033")
        # request.add_query_param('SignSource', "5")
        request.add_query_param('Remark', "应用于web开发试用")

        response = client.do_action(request)
        str(response, encoding='utf-8')
        # 将手机号与验证码写入redis中
        r.set(str(phone), str(code))
        # 生命周期设置60秒
        r.expire(str(phone), 60)
        return Response({'code': 200, 'message': '短信验证码已发送你手机，请注意查收'})
